#ifndef __CONCURRENT_LOCK_HPP
#define __CONCURRENT_LOCK_HPP

namespace concurrent {
  class Lock {
  private:
    pthread_mutex_t mutex;
    pthread_cond_t  cond;
  public:
    Lock() {
      pthread_mutex_init(&(this->mutex), NULL);
      pthread_cond_init(&(this->cond), NULL);
    }
    ~Lock() {
      this->broadcast();
      this->unlock();
    }
    void lock() {
      pthread_mutex_lock(&(this->mutex));
    }
    void unlock() {
      pthread_mutex_unlock(&(this->mutex));
    }
    void wait() {
      pthread_cond_wait(&(this->cond), &(this->mutex));
    }
    void signal() {
      pthread_cond_signal(&(this->cond));
    }
    void broadcast() {
      pthread_cond_broadcast(&(this->cond));
    }
  };

  class synchronizer {
  private:
    Lock& lock;
  public:
    synchronizer(Lock& l)  : lock(l) {}
    ~synchronizer() { lock.unlock(); }
  };

}

#endif
